package bl.controller;

import java.util.ArrayList;

import po.BookInventoryPO;
import po.BookPO;
import po.MemberPO;
import po.SaleItemPO;

import database.factory.BookDataFactory;
import database.factory.BookDataFactoryImpl;
import database.factory.BookInventoryDataFactory;
import database.factory.BookInventoryDataFactoryImpl;
import database.factory.MemberDataFactory;
import database.factory.MemberDataFactoryImpl;
import database.service.BookDataService;
import database.service.BookInventoryDataService;
import database.service.MemberDataService;

import vo.SaleItemVO;
import vo.BLToViewResultMessage;
import exception.BookInventoryNotFoundException;
import exception.ItemNotEnoughException;
import exception.ItemNotFoundException;
import exception.MemberNotFoundException;
import bl.auxiliary.SaleItemList;
import bl.service.TrolleyManagementBLService;

public class TrolleyManagementController implements TrolleyManagementBLService {

	public TrolleyManagementController() {
		super();
	}

	@Override
	public ArrayList<SaleItemVO> getTrolley(int memberID)
			throws MemberNotFoundException {
		MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
		MemberDataService memberDataService = memberDataFactory
				.getMemberDataService();
		memberDataService.load();
		MemberPO member = memberDataService.find(memberID);

		if (member == null) {
			throw new MemberNotFoundException();
		}

		ArrayList<SaleItemPO> saleItemPOs = member.getTrolley();
		if (saleItemPOs == null) {
			return null;
		}

		BookDataFactory bookDataFactory = new BookDataFactoryImpl();
		BookDataService bookDataService = bookDataFactory.getBookDataService();
		bookDataService.load();
		
		ArrayList<SaleItemVO> saleItemVOs = new ArrayList<SaleItemVO>();
		for (int i = 0; i < saleItemPOs.size(); i++) {
			int id = saleItemPOs.get(i).getBookID();
			BookPO bookPO = bookDataService.find(id);
			if (bookPO == null) {
				continue;
			}
			SaleItemVO saleItemVO = new SaleItemVO(bookPO, saleItemPOs.get(i).getQuantity());
			saleItemVOs.add(saleItemVO);
		}
		return saleItemVOs;
	}

	@Override
	public BLToViewResultMessage addItem(int memberID, SaleItemVO saleItem)
			throws MemberNotFoundException, ItemNotEnoughException,
			ItemNotFoundException, BookInventoryNotFoundException {
		MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
		MemberDataService memberDataService = memberDataFactory
				.getMemberDataService();
		memberDataService.load();

		MemberPO member = memberDataService.find(memberID);
		if (member == null) {
			throw new MemberNotFoundException();
		}

		BookInventoryDataFactory bookInventoryDataFactory = new BookInventoryDataFactoryImpl();
		BookInventoryDataService bookInventoryDataService = bookInventoryDataFactory
				.getBookInventoryDataService();
		bookInventoryDataService.load();
		BookInventoryPO bookInventory = bookInventoryDataService.find(saleItem
				.getSaleItemPO().getBookID());
		if (bookInventory == null) {
			throw new BookInventoryNotFoundException();
		}
		if (bookInventory.getAvailableQuantity() < saleItem.getSaleItemPO()
				.getQuantity()) {
			throw new ItemNotEnoughException();
		}

		SaleItemList saleItemList = new SaleItemList(member);
		boolean add = saleItemList.addItem(saleItem.getSaleItemPO());
		if (!add) {
			return null;
		}

		memberDataService.update(member);
		memberDataService.save();
		
		return BLToViewResultMessage.ADD_SALE_ITEM_SUCCESS;
	}

	@Override
	public BLToViewResultMessage deleteItem(int memberID, int bookID)
			throws MemberNotFoundException, ItemNotFoundException {
		MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
		MemberDataService memberDataService = memberDataFactory
				.getMemberDataService();
		memberDataService.load();

		MemberPO member = memberDataService.find(memberID);
		if (member == null) {
			throw new MemberNotFoundException();
		}

		SaleItemList saleItemList = new SaleItemList(member);
		boolean remove = saleItemList.removeItem(bookID);
		if (!remove) {
			return null;
		}

		memberDataService.update(member);
		memberDataService.save();

		return BLToViewResultMessage.REMOVE_SALE_ITEM_SUCCESS;
	}

	@Override
	public BLToViewResultMessage modifyQuantity(int memberID, int bookID,
			SaleItemVO saleItem) throws MemberNotFoundException,
			ItemNotFoundException, BookInventoryNotFoundException,
			ItemNotEnoughException {
		MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
		MemberDataService memberDataService = memberDataFactory
				.getMemberDataService();
		memberDataService.load();

		MemberPO member = memberDataService.find(memberID);
		if (member == null) {
			throw new MemberNotFoundException();
		}

		BookInventoryDataFactory bookInventoryDataFactory = new BookInventoryDataFactoryImpl();
		BookInventoryDataService bookInventoryDataService = bookInventoryDataFactory
				.getBookInventoryDataService();
		bookInventoryDataService.load();
		BookInventoryPO bookInventory = bookInventoryDataService.find(bookID);
		if (bookInventory == null) {
			throw new BookInventoryNotFoundException();
		}
		if (bookInventory.getAvailableQuantity() < saleItem.getSaleItemPO()
				.getQuantity()) {
			throw new ItemNotEnoughException();
		}

		int newQuantity = saleItem.getSaleItemPO().getQuantity();
		SaleItemList saleItemList = new SaleItemList(member);
		boolean modify = saleItemList.changeQuantity(bookID, newQuantity);
		if (!modify) {
			return null;
		}

		memberDataService.update(member);
		memberDataService.save();

		return BLToViewResultMessage.CHANGE_QUANTITY_SUCCESS;
	}

	@Override
	public double getTotalPrice(int memberID) throws MemberNotFoundException {
		MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
		MemberDataService memberDataService = memberDataFactory
				.getMemberDataService();
		memberDataService.load();

		MemberPO member = memberDataService.find(memberID);
		if (member == null) {
			throw new MemberNotFoundException();
		}
		
		SaleItemList saleItemList = new SaleItemList(member);
		double total = saleItemList.getTotal();
		return total;
	}

}
